package com.photoeditor.demo.model.filedownload;

import android.support.annotation.NonNull;

import com.common.base.ComponentContext;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 基于{@link FileDownloader} 封装的下载管理类， 扩展接口支持多对一的下载监听
 * Created by edward on 17-11-14.
 */

public class FileDownloadManager {
    private static FileDownloadManager sInstance;
    private static final int MAX_CONCURRENT_TASK = 6; // 默认最大同时并发下载数

    private List<DownloadListener> mAllDownloadListener;
    private FileDownloadManager() {
        FileDownloader.setup(ComponentContext.getContext());
        FileDownloader.getImpl().setMaxNetworkThreadCount(MAX_CONCURRENT_TASK);
        mAllDownloadListener = new CopyOnWriteArrayList<>();
    }
    public static synchronized FileDownloadManager getInstance() {
        if (sInstance == null) {
            sInstance = new FileDownloadManager();
        }
        return sInstance;
    }

    /**
     * 开始下载 <br>
     * 相同链接和下载文件路径则认为是同一个任务
     *
     * @param url
     * @param downloadPathName
     */
    public void startDownload(String url, String downloadPathName) {
        FileDownloader.getImpl().create(url)
                .setPath(downloadPathName)
                .setAutoRetryTimes(1)
                .setListener(mQueueTarget)
                .start();
    }

    public void startDownload(DownloadListener listener) {
        startDownload(listener.getUrl(), listener.getDownloadPathName());
        addDownloadListener(listener);
    }

    public void pauseDownload(DownloadListener listener) {
        for (DownloadListener downloadListener : mAllDownloadListener) {
            if (downloadListener.equals(listener)) {
                FileDownloader.getImpl().pause(downloadListener);
            }
        }
    }

    /**
     * 获取下载状态
     * @param listener
     * @return {@link com.liulishuo.filedownloader.model.FileDownloadStatus#completed}
     */
    public byte getStatus(@NonNull DownloadListener listener) {
        return getStatus(listener.getUrl(),listener.getDownloadPathName());
    }

    /**
     * 获取下载状态
     * @param url
     * @param downloadPathName
     * @return {@link com.liulishuo.filedownloader.model.FileDownloadStatus#completed}
     */
    public byte getStatus(String url, String downloadPathName) {
        return FileDownloader.getImpl().getStatus(url, downloadPathName);
    }

    public synchronized void addDownloadListener(DownloadListener listener) {
        mAllDownloadListener.add(listener);
    }

    public synchronized void removeDownloadListener(DownloadListener listener) {
        mAllDownloadListener.remove(listener);
    }

    private final FileDownloadListener mQueueTarget = new FileDownloadListener() {
        @Override
        protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.pending(task, soFarBytes, totalBytes);
                }
            }
        }

        @Override
        protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.connected(task, etag, isContinue, soFarBytes, totalBytes);
                }
            }
        }

        @Override
        protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.progress(task, soFarBytes, totalBytes);
                }
            }
        }

        @Override
        protected void blockComplete(BaseDownloadTask task) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.blockComplete(task);
                }
            }
        }

        @Override
        protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.retry(task, ex, retryingTimes, soFarBytes);
                }
            }
        }

        @Override
        protected void completed(BaseDownloadTask task) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.completed(task);
                }
            }
        }

        @Override
        protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.paused(task, soFarBytes, totalBytes);
                }
            }
        }

        @Override
        protected void error(BaseDownloadTask task, Throwable e) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.error(task, e);
                }
            }
        }

        @Override
        protected void warn(BaseDownloadTask task) {
            for (DownloadListener downloadListener : mAllDownloadListener) {
                if (downloadListener.match(task)) {
                    downloadListener.warn(task);
                }
            }
        }
    };

}
